package com.yidu.best.aspect;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.yidu.best.basicSetup.exchange.util.IDUtil;
import com.yidu.best.systemManagement.systemLog.domian.Log;
import com.yidu.best.systemManagement.systemLog.service.LogService;
import com.yidu.best.systemManagement.userControl.domain.User;

@Aspect
@Component
public class LogAspect {
	@Autowired
    private LogService logController;
	private User user;
	@Pointcut(value = "execution(* com.yidu.best.*.*.controller..*.do*(..))")
    public void log(){}

    @After(value="log()")
    public void afterThrowingMethod(JoinPoint joinPoint){
    	HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    	if (user==null){
            user = (User) request.getAttribute("user");
        }
        //获取切入的方法名
        String methodName= joinPoint.getSignature().getName();
        LogALG(request, user, "doLogin",methodName,"登录","基础->登录");
        LogALG(request, user, "doUserDate",methodName,"查看用户表","系统管理->用户");
        LogALG(request, user, "doExchange",methodName,"查看品种汇率","基础设置->品种汇率");
    }
    
    /**
     * 日志插入方法
     * @param request 请求对象
     * @param user 用户对象
     * @param targetMethod 目标方法
     * @param methodName 正在执行的方法名
     * @param motion 事件
     * @param source 资源
     */
    private void LogALG(HttpServletRequest request, User user,String  targetMethod,String methodName,String motion,String source) {
        if (targetMethod.equals(methodName)){
            if (user!=null){
                Log log = new Log();
                String clientIp = getIpAddress(request);
                log.setLogId(IDUtil.getUUID());
                log.setComputerIP(clientIp);
                log.setMotion(motion);
                log.setUserId(user.getUserId());
                log.setUserName(user.getUserName());
                log.setLogTime(new Date());
                log.setSource(source);
                logController.addLog(log);
        }
            }
    }
    
    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址。
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？ 
     * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串
     * @param request
     * @return
     */
    private static String getIpAddress(HttpServletRequest request) {  
        String ip = request.getHeader("x-forwarded-for");  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("WL-Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_CLIENT_IP");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getRemoteAddr();  
            if("127.0.0.1".equals(ip)||"0:0:0:0:0:0:0:1".equals(ip)){
                //根据网卡取本机配置的IP
                 InetAddress inet=null;
                 try {
                     inet = InetAddress.getLocalHost();
                 } catch (UnknownHostException e) {
                     e.printStackTrace();
                 }
                     ip= inet.getHostAddress();
            }
        }  
        return ip;
    }
}
